package com.demo.mutilThread;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class BlockingQqeue<T> {
    //1 任务队列ArrayDeque
    private Deque<T> queue = new ArrayDeque<T>(5);
    //2 锁
    private ReentrantLock lock = new ReentrantLock();
    //3 生产者条件变量
    private Condition fullWaitSet = lock.newCondition();
    //4 消费者条件变量
    private Condition emptyWaitSet = lock.newCondition();
    //5 容量
    private int capcity;

    public BlockingQqeue(int capcity) {
        this.capcity = capcity;
    }

    //阻塞获取
    public T take(){
        lock.lock();
        try {
            while (queue.isEmpty()) {
                try {
                    emptyWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
               // fullWaitSet.signal();
            }
            T t = queue.removeFirst();
            fullWaitSet.signal();
            return t;
        } finally {
            lock.unlock();
        }
    }
    //阻塞添加
    public  void put(T element) {
        lock.lock();
        try {
            while (queue.size() == capcity) {
                try {
                    fullWaitSet.await();
                    //唤醒队列
                    emptyWaitSet.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.addLast(element);
        } finally {
            lock.unlock();
        }
    }
    //获取大小
    public int size(){
      lock.lock();
        try {
            return queue.size();
        } finally {
           lock.unlock();
        }
    }
}
